import os
from datetime import datetime

from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.db.models import Q, F
from django.utils.decorators import method_decorator
from django.views import View
from django.shortcuts import render, get_object_or_404, redirect
from django.http import JsonResponse, HttpResponse

from learning_learning.settings import MEDIA_URL
from .froms import PostForm
from .models import Post, Comment, Like

from Login_regist.models import Follow, Messages, UserDetails


def Message_content(user):
    user = User.objects.get(id=user.id)
    senders = User.objects.filter(sent_messages__receiver=user).distinct()
    senders_data = []
    for sender in senders:
        is_following = Follow.objects.filter(follower=user.id, following=sender.id).exists()
        messages = Messages.objects.filter(
            Q(sender=user, receiver=sender) | Q(sender=sender, receiver=user)
        ).order_by('-sent_at')
        last_message = messages.first()
        userdetails = UserDetails.objects.get(user=sender)
        senders_data.append({
            'id': sender.id,
            'username': sender.username,
            'is_following': is_following,
            'message': str(last_message),
            'cover': userdetails.cover,
        })

    return senders_data


class ChatView(View):
    def get(self, request, id=None):
        if id is None:
            last_interact = Messages.objects.filter(
                Q(sender=request.user) | Q(receiver=request.user)
            ).order_by('-sent_at').first()
            if last_interact:
                id = last_interact.receiver.id if last_interact.sender == request.user else last_interact.sender.id
            # else:
            #     return redirect('none_msg')
        receiver = User.objects.get(id=id)
        rec_detail = UserDetails.objects.get(user=receiver)

        messages = Messages.objects.filter(
            (Q(sender=request.user) & Q(receiver=receiver)) | (Q(sender=receiver) & Q(receiver=request.user))
        ).order_by('sent_at')
        messages.filter(receiver=request.user, read=False).update(read=True)

        sender = Message_content(request.user)
        user = User.objects.get(username=request.user)
        userdetails = UserDetails.objects.get(user=user)

        return render(request, 'templates/chat/chat.html',
                      {'username': request.user.username, 'senders': sender, 'messages': messages, 'user': userdetails,
                       'receiver': rec_detail})

    def post(self, request, id=None):
        if id is None:
            last_interact = Messages.objects.filter(
                Q(sender=request.user) | Q(receiver=request.user)
            ).order_by('-sent_at').first()
            if last_interact:
                id = last_interact.receiver.id if last_interact.sender == request.user else last_interact.sender.id
            else:
                redirect('none_msg')
        receiver = User.objects.get(id=id)
        message = request.POST.get('message')
        if message:
            message_user = Messages(sender=request.user, receiver=receiver, content=message)
            message_user.save()
        return redirect('chat')
        # return render(request,'user/chat.html',{'username':request.user.username,'mistake':mistake})


class ChatMessageView(View):
    def get(self, request, id):
        receiver = User.objects.get(id=id)
        rec_detail = UserDetails.objects.get(user=receiver)
        messages = Messages.objects.filter(
            (Q(sender=request.user) & Q(receiver=receiver)) | (Q(sender=receiver) & Q(receiver=request.user))
        ).order_by('sent_at')
        messages.filter(receiver=request.user, read=False).update(read=True)
        sender = Message_content(request.user)
        user = User.objects.get(username=request.user)
        userdetails = UserDetails.objects.get(user=user)
        return render(request, 'templates/chat/chat.html',
                      {'messages': messages, 'username': request.user.username, 'senders': sender,
                       'receiver': rec_detail, 'user': userdetails})

    def post(self, request, id=None):
        if id is None:
            last_interact = Messages.objects.filter(
                Q(sender=request.user) | Q(receiver=request.user)
            ).order_by('-sent_at').first()
            if last_interact:
                id = last_interact.receiver.id if last_interact.sender == request.user else last_interact.sender.id
            else:
                redirect('none_msg')
        receiver = User.objects.get(id=id)
        try:
            message = request.POST.get('message')
        except Exception as e:
            print(e)
        message_user = Messages(sender=request.user, receiver=receiver, content=message)
        message_user.save()
        return redirect('chat_msg', id)


def community_home(request, **kwargs):
    posts = Post.objects.all()
    username = request.user.username
    user = User.objects.get(username=request.user)
    userdetails = UserDetails.objects.get(user=user)
    return HttpResponse(
        render(request, 'templates/chat/community.html', {'posts': posts, 'username': username, 'user': userdetails}))


def post_detail(request, id):
    try:
        post = Post.objects.get(id=id)
    except Post.DoesNotExist:
        return redirect('not_find')

    Post.objects.filter(id=id).update(page_view=F('page_view')+1)
    user = post.user
    userdetails = UserDetails.objects.get(user=user)

    # work_count follow_count like_count_all collect_count comment_count like_count
    # 得到作者的所有作品(post) work_count
    user_posts = Post.objects.filter(user=user).order_by('-created_at')
    work_count = user_posts.count()

    # 得到作者的所有粉丝(follow) follow_count
    fans = Follow.objects.filter(following=user).values_list('following', flat=True)
    follow_count = fans.count()

    # 得到作者所有post获赞的总数 like_count_all
    like_count_all = 0
    for user_post in user_posts:
        post_like = Like.objects.filter(post=user_post).count()
        like_count_all += post_like

    # 得到作者的所有收藏(collect) collect_count

    # 得到本篇帖子的评论数量
    post_comment = Comment.objects.filter(post=post).order_by('-created_at')
    comment_count = post_comment.count()

    # 得到本篇帖子的点赞量
    post_like = Like.objects.filter(post=post)
    like_count = post_like.count()

    # 获取所有父级评论 (即parent_comment为空的评论)
    parent_comments = Comment.objects.filter(post=post, parent_comment__isnull=True).order_by('-created_at')
    # 构造评论数据结构，包含子级评论
    comment_data = []
    for parent in parent_comments:
        children = Comment.objects.filter(parent_comment=parent).order_by('-created_at')
        parent_userdetails = UserDetails.objects.get(user=parent.user)
        comment_data.append({
            'parent': parent,
            'children': children,
            'userdetails': parent_userdetails,
        })
    context = {
        'post': post,
        'comment_data': comment_data,
    }
    return HttpResponse(render(request, 'templates/chat/post.html', {
        'author': userdetails,
        'user': userdetails,
        'username': request.user.username,
        'work_count': work_count,
        'follow_count': follow_count,
        'like_count': like_count_all,
        'collect_count': '无',
        'post': post,
        'like_count_all': like_count,
        'comment_count': comment_count,
        'comments_data': context['comment_data'],
    }))


def load_child_comments(request, parent_id):
    """
    异步加载子级评论
    :param request:
    :param id:
    :return:
    """
    parent = get_object_or_404(Comment, id=parent_id)
    child_comments = Comment.objects.filter(parent_comment=parent).order_by('-created_at')

    child_comments_list = [
        {
            'username': c.user.username,
            'content': c.content,
            'created_at': c.created_at.strftime('%Y-%m-%d %H:%M'),
            'child_comments': list(
                Comment.objects.filter(parent_comment=c).order_by('-created_at').values('id', 'user_id', 'post_id',
                                                                                        'content', 'parent_comment_id',
                                                                                        'created_at')),
            'cover': UserDetails.objects.get(user=c.user).cover,
            'id': c.id,

        }
        for c in child_comments
    ]
    return JsonResponse({'child_comments': child_comments_list})


def add_comment(request):
    """
    异步提交评论
    :param request:
    :return:
    """
    if request.method == "POST":
        post_id = request.POST.get('post_id')
        content = request.POST.get('content')
        parent_id = request.POST.get('parent_id', None)

        post = Post.objects.get(id=post_id)
        # 获取当前用户
        user = request.user

        parent_comment = Comment.objects.get(id=parent_id) if parent_id else None

        new_comment = Comment.objects.create(
            user=user,
            post=post,
            content=content,
            parent_comment=parent_comment
        )
        return JsonResponse({
            'username': new_comment.user.username,
            'content': new_comment.content,
            'created_at': new_comment.created_at.strftime('%Y-%m-%d %H:%M'),
            'parent_id': parent_id,
        })
    return JsonResponse({
        'error': 'Invalid request'
    },
        status=400)


class CreatePost(View):
    @method_decorator(login_required)  # 调用login_required装饰器 判断用户是否登录的装饰器
    def get(self, request):
        form = PostForm()
        user = UserDetails.objects.get(user=request.user)
        return render(request, 'templates/chat/create_post.html', {'form': form, 'username': request.user.username,'user':user})

    def post(self, request):
        form = PostForm(request.POST, request.FILES)

        if form.is_valid():
            title = form.cleaned_data.get('title')
            desc = form.cleaned_data.get('desc')
            content = form.cleaned_data.get('content')
            cover = form.cleaned_data.get('cover')
            user = request.user
            # 上传图片到ubantu服务器
            # 文件名定义：获取发布时间的时间戳和原有文件名拼接 为了避免用户上传的文件名称重复产生冲突
            file_name = f'{datetime.now().strftime("%Y%m%d%H%M%S")}_{cover.name}'
            # 找到并且打开图片或视频文件 这里也要用到拼接先找到地址MEDIA_ROOT再在地址文件夹里找到文件
            # 用fp代替打开的文件名称 wb方式打开文件 若没有就会自动创建文件
            with open(os.path.join(MEDIA_URL, file_name), 'wb') as fp:
                # chunks()方式可以将上传的cover数据拆分成许多的包来避免用read方式读取文件会因为文件过长而报错
                # 然后只需将读取拆分后的包依次写入文件就行了
                for data in cover.chunks():
                    fp.write(data)
                Post.objects.create(title=title, desc=desc, content=content,
                                           cover=file_name, user=user, )
        else:
            print('未通过')
        return render(request, 'templates/chat/create_post.html', {'form': form,'username': request.user.username})